"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;
var _vue = require("vue");
var _ui = require("../../ui");
var _dom = require("../../ui/src/dom");
var _widgetInfo = require("./widget-info");
var _xeUtils = _interopRequireDefault(require("xe-utils"));
var _button = _interopRequireDefault(require("../../button/src/button"));
var _layoutWidget = _interopRequireDefault(require("./layout-widget"));
var _layoutPreview = _interopRequireDefault(require("./layout-preview"));
var _layoutSetting = _interopRequireDefault(require("./layout-setting"));
var _layoutStyle = _interopRequireDefault(require("./layout-style"));
var _defaultSettingData = require("./default-setting-data");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var _default = exports.default = (0, _vue.defineComponent)({
  name: 'VxeFormDesign',
  props: {
    size: {
      type: String,
      default: () => (0, _ui.getConfig)().formDesign.size || (0, _ui.getConfig)().size
    },
    config: Object,
    height: {
      type: [String, Number],
      default: () => (0, _ui.getConfig)().formDesign.height
    },
    widgets: {
      type: Array,
      default: () => _xeUtils.default.clone((0, _ui.getConfig)().formDesign.widgets) || []
    },
    showHeader: {
      type: Boolean,
      default: () => (0, _ui.getConfig)().formDesign.showHeader
    },
    showPc: {
      type: Boolean,
      default: () => (0, _ui.getConfig)().formDesign.showPc
    },
    showMobile: {
      type: Boolean,
      default: () => (0, _ui.getConfig)().formDesign.showMobile
    },
    formRender: Object
  },
  emits: ['click-widget', 'add-widget', 'copy-widget', 'remove-widget', 'drag-widget'],
  setup(props, context) {
    const {
      emit,
      slots
    } = context;
    const xID = _xeUtils.default.uniqueId();
    const refElem = (0, _vue.ref)();
    const refLayoutStyle = (0, _vue.ref)();
    const {
      computeSize
    } = (0, _ui.useSize)(props);
    const reactData = (0, _vue.reactive)({
      formData: {},
      widgetConfigs: [],
      widgetObjList: [],
      dragWidget: null,
      sortWidget: null,
      activeWidget: null
    });
    const internalData = (0, _vue.reactive)({});
    const refMaps = {
      refElem
    };
    const computeMaps = {
      computeSize
    };
    const $xeFormDesign = {
      xID,
      props,
      context,
      reactData,
      internalData,
      getRefMaps: () => refMaps,
      getComputeMaps: () => computeMaps
    };
    const createWidget = name => {
      return new _widgetInfo.FormDesignWidgetInfo($xeFormDesign, name, reactData.widgetObjList);
    };
    const createEmptyWidget = () => {
      return new _widgetInfo.FormDesignWidgetInfo($xeFormDesign, '', reactData.widgetObjList);
    };
    const loadConfig = config => {
      if (config) {
        const {
          formConfig,
          widgetData
        } = config;
        if (formConfig) {
          loadFormConfig(formConfig);
        }
        if (widgetData) {
          loadWidgetData(widgetData);
        }
      }
      const {
        activeWidget,
        widgetObjList
      } = reactData;
      if (activeWidget) {
        const rest = _xeUtils.default.findTree(widgetObjList, item => item.id === activeWidget.id, {
          children: 'children'
        });
        if (rest) {
          reactData.activeWidget = rest.item;
        } else {
          reactData.activeWidget = widgetObjList[0] || null;
        }
      } else {
        reactData.activeWidget = widgetObjList[0] || null;
      }
      return (0, _vue.nextTick)();
    };
    const reloadConfig = config => {
      clearConfig();
      return loadConfig(config);
    };
    const getFormConfig = () => {
      return _xeUtils.default.clone(reactData.formData, true);
    };
    const loadFormConfig = data => {
      reactData.formData = Object.assign({}, createSettingForm(), data);
      return (0, _vue.nextTick)();
    };
    const getWidgetById = id => {
      const {
        widgetObjList
      } = reactData;
      if (id) {
        const widgetId = _xeUtils.default.toNumber(id);
        const rest = _xeUtils.default.findTree(widgetObjList, item => item && item.id === widgetId, {
          children: 'children'
        });
        if (rest) {
          return rest.item;
        }
      }
      return null;
    };
    const getWidgetData = () => {
      const objList = _xeUtils.default.clone(reactData.widgetObjList, true);
      _xeUtils.default.eachTree(objList, item => {
        item.model.value = null;
      }, {
        children: 'children'
      });
      return objList;
    };
    const loadWidgetData = widgetData => {
      reactData.widgetObjList = (widgetData || []).map(item => (0, _widgetInfo.configToWidget)(item));
      return (0, _vue.nextTick)();
    };
    const openStyleSetting = () => {
      const $layoutStyle = refLayoutStyle.value;
      if ($layoutStyle) {
        $layoutStyle.openStylePreview();
      }
      return (0, _vue.nextTick)();
    };
    const clearConfig = () => {
      reactData.widgetObjList = [];
      initSettingForm();
      return (0, _vue.nextTick)();
    };
    const formDesignMethods = {
      dispatchEvent(type, params, evnt) {
        emit(type, (0, _ui.createEvent)(evnt, {
          $xeFormDesign
        }, params));
      },
      createWidget,
      createEmptyWidget,
      getConfig() {
        return {
          formConfig: getFormConfig(),
          widgetData: getWidgetData()
        };
      },
      clearConfig,
      loadConfig,
      reloadConfig,
      getFormConfig,
      loadFormConfig,
      getWidgetById,
      getFormData() {
        const {
          widgetObjList
        } = reactData;
        const formData = {};
        _xeUtils.default.eachTree(widgetObjList, widget => {
          formData[widget.field] = null;
        }, {
          children: 'children'
        });
        return formData;
      },
      getWidgetData,
      loadWidgetData,
      refreshPreviewView() {
        const $layoutStyle = refLayoutStyle.value;
        if ($layoutStyle) {
          $layoutStyle.updatePreviewView();
        }
        return (0, _vue.nextTick)();
      },
      openStyleSetting
    };
    const updateWidgetConfigs = () => {
      const {
        widgets
      } = props;
      const widgetConfs = [];
      const baseWidgets = [];
      const layoutWidgets = [];
      const advancedWidgets = [];
      const customGroups = [];
      _ui.renderer.forEach((item, name) => {
        const {
          createFormDesignWidgetConfig
        } = item;
        if (createFormDesignWidgetConfig) {
          const widthItem = createWidget(name);
          const widgetConf = (0, _widgetInfo.getWidgetConfig)(name);
          const widgetCustomGroup = (0, _widgetInfo.getWidgetConfigCustomGroup)(name, $xeFormDesign);
          // 如果自定义组
          if (widgetCustomGroup) {
            const cusGroup = customGroups.find(item => item.title === widgetCustomGroup);
            if (cusGroup) {
              cusGroup.children.push(widthItem);
            } else {
              customGroups.push({
                title: widgetCustomGroup,
                children: [widthItem]
              });
            }
          } else {
            switch (widgetConf.group) {
              case 'layout':
                layoutWidgets.push(widthItem);
                break;
              case 'advanced':
                advancedWidgets.push(widthItem);
                break;
              default:
                // 已废弃 title
                if (!['title'].includes(widthItem.name)) {
                  baseWidgets.push(widthItem);
                }
                break;
            }
          }
        }
      });
      if (baseWidgets.length) {
        widgetConfs.push({
          group: 'base',
          children: baseWidgets
        });
      }
      if (layoutWidgets.length) {
        widgetConfs.push({
          group: 'layout',
          children: layoutWidgets
        });
      }
      if (advancedWidgets.length) {
        widgetConfs.push({
          group: 'advanced',
          children: advancedWidgets
        });
      }
      if (customGroups.length) {
        widgetConfs.push(...customGroups);
      }
      if (widgets && widgets.length) {
        reactData.widgetConfigs = props.widgets.map(config => {
          return {
            title: config.customGroup,
            group: config.group,
            children: config.children ? config.children.map(name => {
              const widthItem = createWidget(name);
              return widthItem;
            }) : []
          };
        });
      } else {
        reactData.widgetConfigs = widgetConfs;
      }
    };
    const validWidgetUnique = widgetName => {
      const {
        widgetObjList
      } = reactData;
      const widgetConf = (0, _widgetInfo.getWidgetConfig)(widgetName);
      if (widgetConf.unique) {
        const existWidgetList = [];
        _xeUtils.default.eachTree(widgetObjList, obj => {
          if (obj.name === widgetName) {
            existWidgetList.push(obj);
          }
        }, {
          children: 'children'
        });
        const status = existWidgetList.length < 1;
        if (!status) {
          if (_ui.VxeUI.modal) {
            _ui.VxeUI.modal.message({
              content: (0, _ui.getI18n)('vxe.formDesign.error.wdFormUni'),
              status: 'error',
              id: 'wdFormUni'
            });
          }
        }
        return status;
      }
      return true;
    };
    const formDesignPrivateMethods = {
      validWidgetUnique,
      handleClickWidget(evnt, item) {
        if (item && item.name) {
          evnt.stopPropagation();
          reactData.activeWidget = item;
          formDesignMethods.dispatchEvent('click-widget', {
            widget: item
          }, evnt);
        }
      },
      handleCopyWidget(evnt, widget) {
        const {
          widgetObjList
        } = reactData;
        const rest = _xeUtils.default.findTree(widgetObjList, obj => obj.id === widget.id, {
          children: 'children'
        });
        if (rest) {
          evnt.stopPropagation();
          if (validWidgetUnique(widget.name)) {
            const {
              path
            } = rest;
            const rootIndex = Number(path[0]);
            const newWidget = createWidget(widget.name);
            // 标题副本
            if (newWidget.title) {
              newWidget.title = (0, _ui.getI18n)('vxe.formDesign.widget.copyTitle', [`${widget.title}`.replace((0, _ui.getI18n)('vxe.formDesign.widget.copyTitle', ['']), '')]);
            }
            if (rootIndex >= widgetObjList.length - 1) {
              widgetObjList.push(newWidget);
            } else {
              widgetObjList.splice(rootIndex + 1, 0, newWidget);
            }
            reactData.activeWidget = newWidget;
            reactData.widgetObjList = [...widgetObjList];
            formDesignMethods.dispatchEvent('copy-widget', {
              widget,
              newWidget
            }, evnt);
          }
        }
      },
      handleRemoveWidget(evnt, widget) {
        const {
          widgetObjList
        } = reactData;
        const rest = _xeUtils.default.findTree(widgetObjList, obj => obj.id === widget.id, {
          children: 'children'
        });
        if (rest) {
          const {
            index,
            parent,
            items
          } = rest;
          evnt.stopPropagation();
          if (index >= items.length - 1) {
            reactData.activeWidget = items[index - 1];
          } else {
            reactData.activeWidget = items[index + 1] || null;
          }
          // 如果是行控件，使用空的控件占位
          if (parent && parent.name === 'row') {
            items[index] = createEmptyWidget();
          } else {
            items.splice(index, 1);
          }
          reactData.widgetObjList = [...widgetObjList];
          formDesignMethods.dispatchEvent('remove-widget', {
            widget
          }, evnt);
        }
      }
    };
    const createSettingForm = () => {
      const {
        formRender,
        showPc,
        showMobile
      } = props;
      let conf = (0, _defaultSettingData.getDefaultSettingFormData)({
        pcVisible: showPc,
        mobileVisible: showMobile
      });
      // 如果为自定义渲染
      if (formRender) {
        const compConf = _ui.renderer.get(formRender.name);
        const createFormConfig = compConf ? compConf.createFormDesignSettingFormConfig : null;
        conf = (createFormConfig ? createFormConfig({}) : {}) || {};
      }
      return conf;
    };
    const initSettingForm = () => {
      reactData.formData = createSettingForm();
    };
    const openStylePreviewEvent = () => {
      openStyleSetting();
    };
    Object.assign($xeFormDesign, formDesignMethods, formDesignPrivateMethods);
    const renderLayoutHeader = () => {
      const extraSlot = slots.extra;
      return (0, _vue.h)('div', {
        class: 'vxe-form-design--header-wrapper'
      }, [(0, _vue.h)('div', {
        class: 'vxe-form-design--header-left'
      }), (0, _vue.h)('div', {
        class: 'vxe-form-design--header-middle'
      }), (0, _vue.h)('div', {
        class: 'vxe-form-design--header-right'
      }, [extraSlot ? (0, _vue.h)('div', {
        class: 'vxe-form-design--header-extra'
      }, extraSlot({})) : (0, _ui.renderEmptyElement)($xeFormDesign), (0, _vue.h)('div', {
        class: 'vxe-form-design--header-setting'
      }, [(0, _vue.h)(_button.default, {
        mode: 'text',
        status: 'primary',
        icon: (0, _ui.getIcon)().FORM_DESIGN_STYLE_SETTING,
        content: (0, _ui.getI18n)('vxe.formDesign.styleSetting.btn'),
        onClick: openStylePreviewEvent
      })])])]);
    };
    const renderVN = () => {
      const {
        height,
        showHeader
      } = props;
      const vSize = computeSize.value;
      const headerSlot = slots.header;
      const footerSlot = slots.footer;
      return (0, _vue.h)('div', {
        ref: refElem,
        class: ['vxe-form-design', {
          [`size--${vSize}`]: vSize
        }],
        style: height ? {
          height: (0, _dom.toCssUnit)(height)
        } : null
      }, [showHeader || headerSlot ? (0, _vue.h)('div', {
        class: 'vxe-form-design--header'
      }, headerSlot ? headerSlot({}) : renderLayoutHeader()) : (0, _vue.createCommentVNode)(), (0, _vue.h)('div', {
        class: 'vxe-form-design--body'
      }, [(0, _vue.h)(_layoutWidget.default), (0, _vue.h)(_layoutPreview.default), (0, _vue.h)(_layoutSetting.default), (0, _vue.h)(_layoutStyle.default, {
        ref: refLayoutStyle
      })]), footerSlot ? (0, _vue.h)('div', {
        class: 'vxe-form-design--footer'
      }, footerSlot ? footerSlot({}) : []) : (0, _vue.createCommentVNode)()]);
    };
    $xeFormDesign.renderVN = renderVN;
    (0, _vue.watch)(() => props.widgets, () => {
      updateWidgetConfigs();
    });
    (0, _vue.watch)(() => props.widgets, () => {
      updateWidgetConfigs();
    });
    (0, _vue.watch)(() => props.config, value => {
      loadConfig(value || {});
    });
    initSettingForm();
    updateWidgetConfigs();
    if (props.config) {
      loadConfig(props.config);
    }
    (0, _vue.provide)('$xeFormDesign', $xeFormDesign);
    return $xeFormDesign;
  },
  render() {
    return this.renderVN();
  }
});